<script>
import { getAddress } from '@/api/basic'
import { value as get } from '@/utils/kris_utils'
export default {
  props: {
    value: {
      type: Array,
      required: true,
      default() { return [] }
    }
  },
  data() {
    return {
      addressSelectorProps: {
        lazy: true,
        lazyLoad: async(node, resolve) => {
          try {
            const { level, value } = node
            console.log(value, level)
            const result = await this.getAddress(level === 0 ? '' : value)
            resolve(result.data.map(item => {
              return {
                label: item.name,
                value: item.id,
                leaf: item.level >= 3
              }
            }))
          } catch (error) {
            this.$message.error(error.message)
          }
        }
      }
    }
  },
  computed: {
    attrs() {
      const attrs = { ...this.$attrs }
      attrs['props'] = this.addressSelectorProps
      attrs['value'] = this.currentValue
      return attrs
    },
    listeners() {
      const listeners = { ...this.$attrs }
      listeners['input'] = this.handleInput
      return listeners
    },
    currentValue: {
      get() {
        if (!Array.isArray(this.value)) { return [] }
        return this.value.map(item => item.value)
      },
      set(value) {
        this.$emit('input', this.pathWithLabel(value))
      }
    }
  },
  methods: {
    async getAddress(id) {
      const result = await getAddress(id)
        .catch(err => {
          throw new Error('获取地址失败')
        })

      if (result.code !== 200 || !Array.isArray(result.data)) { throw new Error('获取地址失败') }

      return result
    },
    handleInput(e) {
      this.currentValue = e
    },
    find(options, path, valueKey = 'value', childrenKey = 'children') {
      if (!Array.isArray(options) || !Array.isArray(path)) { return [] }

      const holder = {
        options,
        path: []
      }

      return path.reduce((prev, current, index) => {
        const target = prev.options.find(item => item[valueKey] === current)

        if (target === null) { return [] }

        prev.options = target[childrenKey]
        prev.path.push(target)

        return index >= (path.length - 1) ? prev.path : prev
      }, holder)
    },
    pathWithLabel(value) {
      /**
             * Kris Mark:
             * 这是 Element UI 级连 选项的列表 树结构
             * 因为 Value 使用了对象之后不支持回显 只能设置为地址的id
             * 但同时在非编辑模式下需要显示地址，重新根据id发请求查太浪费资源
             * 所以使用组件内部维护的列表
             */
      const options = get(this.$refs, 'cascader.$refs.panel.store.nodes')
      if (!Array.isArray(value) || !Array.isArray(options)) { return [] }

      return this
        .find(options, value)
        .map(item => ({ label: item.label, value: item.value }))
    }
  }
}
</script>

<template>
  <el-cascader
    ref="cascader"
    v-bind="attrs"
    v-on="listeners"
  />
</template>

<style lang="scss"></style>
